#    Copyright 2012 Tri-County Electric Cooperative, St. Matthews, South Carolina
#    This file is part of COOPIP.
#    COOPIP is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    COOPIP is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with COOPIP.  If not, see <http://www.gnu.org/licenses/>.

import sys
NeededPaths=['/opt/coopip/djangoproject/include', '/opt/coopip/djangoproject', '/opt/cis', '/opt/oms/', '/opt/amr', '/opt/gis','/opt/gos', '/opt']
for path in NeededPaths:
    if(not path in sys.path):
        sys.path.append(path)
import httplib
import os, csv, shutil, datetime, time, reportlab, djangoproject.settings, datetime
from django.contrib.gis.db import models
from django.contrib.gis.geos import *
from django.http import HttpResponse
from django.contrib.gis import admin
import _mysql as mysql
from django.db import transaction
import django, urllib
import COOPIP_Form
import CIS, AMR, GIS, GOS  #Comment this out before doing a syncdb
from ftplib import FTP
import cPickle
import bs4  #Beautiful Soup

class COOPTalk(models.Model):
    using='default'
    ConnectionString=models.TextField(db_column='serveraddress', null=True, blank=True)
    Header=models.TextField(db_column='headers', null=True, blank=True) #pickled dictionary with header data in a dictionary
    Body=models.TextField(db_column='body', null=True, blank=True)
    CreateDateTime=models.DateTimeField(db_column='createdatetime', null=True, blank=True)
    OutIndicator=models.NullBooleanField(db_column='outindicator', null=True, blank=True)  #Indicates that this command needs to be sent out
    OutDateTime=models.DateTimeField(db_column='outdatetime', null=True, blank=True)   #DateTime when it was sent out, null if it is waiting to go out
    InIndicator=models.NullBooleanField(db_column='inindicator', null=True, blank=True)
    InDateTime=models.DateTimeField(db_column='indatetime', null=True, blank=True)
    Response=models.TextField(db_column='response', null=True, blank=True)
    ResponseDateTime=models.DateTimeField(db_column='responsedatetime', null=True, blank=True)
    LocalProcessingCompleteIndicator=models.NullBooleanField(db_column='localprocessingcompleteindicator', null=True, blank=True)
    URL=models.TextField(db_column='url', null=True, blank=True)
    InResponseReadingChangedNotificationIndicator = models.NullBooleanField(db_column='inresponsereadingchangednotificationindicator', null=True, blank=True)
    class Meta:
        db_table=u'cooptalk'
        app_label='djangoproject'

    @staticmethod
    def SendAllOut():
        COOPTalk.CleanUpLogs()
        COOPTalks=COOPTalk.objects.filter(OutIndicator=True).filter(OutDateTime__isnull=True).order_by('CreateDateTime')
        for i in COOPTalks:
            Connection=httplib.HTTPConnection(i.ConnectionString)
            Header=cPickle.loads(str(i.Header))
            i.OutDateTime=datetime.datetime.now()
            Connection.request("POST", i.URL, i.Body, cPickle.loads(str(i.Header)))
            Response=Connection.getresponse()
            i.Response=Response.read()
            i.ResponseDateTime=datetime.datetime.now()
            i.OutIndicator=False
            i.save()
            Connection.close()

    @staticmethod
    def OutPingURL(ConnectionString='192.168.100.98:80', URL='/Optimum_Web_Service/MultiSpeak/30/MR_Server.asmx'):
        New=COOPTalk()
        New.ConnectionString = ConnectionString
        New.Header=cPickle.dumps({"Content-type":"application/soap+xml", "charset":"utf-8"})
        New.Body = """<?xml version="1.0" encoding="utf-8"?>
                      <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                      <soap12:Header>
                      <MultiSpeakMsgHeader Version="3.0" UserID="DCSI" Pwd="DCSI"
                       AppName="COOPIP"
                       AppVersion="1" Company="TCEC" CSUnits="feet"
                       CoordinateSystem=""
                       Datum=""
                       SessionID="" PreviousSessionID="" ObjectsRemaining=""
                       LastSent="" xmlns="http://www.multispeak.org/Version_3.0" />
                       </soap12:Header>
                       <soap12:Body>
                       <PingURL xmlns="http://www.multispeak.org/Version_3.0" />
                       </soap12:Body>
                       </soap12:Envelope>"""
        New.URL=URL
        New.CreateDateTime=datetime.datetime.now()
        New.OutIndicator=True
        New.save()

    @staticmethod
    def OutGetLatestReadingByMeterNo(MeterNumber, ConnectionString='192.168.100.98:80', URL='/Optimum_Web_Service/MultiSpeak/30/MR_Server.asmx'):
        New=COOPTalk()
        New.ConnectionString=ConnectionString
        New.Header=cPickle.dumps({"Content-type":"application/soap+xml", "charset":"utf-8"})
        New.Body="""<?xml version="1.0" encoding="utf-8"?>
                    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                    <soap12:Header>
                    <MultiSpeakMsgHeader Version="3.0" UserID="DCSI" Pwd="DCSI"
                    AppName="COOPIP"
                    AppVersion="1" Company="TCEC" CSUnits="feet"
                    CoordinateSystem=""
                    Datum=""
                    xmlns="http://www.multispeak.org/Version_3.0" />
                    </soap12:Header>
                    <soap12:Body>
                    <GetLatestReadingByMeterNo xmlns="http://www.multispeak.org/Version_3.0">
                    <meterNo>{{MeterNumber}}</meterNo>
                    </GetLatestReadingByMeterNo>
                    </soap12:Body>
                    </soap12:Envelope>""".replace('{{MeterNumber}}', MeterNumber)
        New.URL=URL
        New.CreateDateTime=datetime.datetime.now()
        New.OutIndicator=True
        New.save()
   
    @staticmethod
    def OutInitiateMeterReadByMeterNumber(MeterNumber, ConnectionString='192.168.100.98:80', URL='/Optimum_Web_Service/MultiSpeak/30/MR_Server.asmx'):
        New=COOPTalk()
        New.ConnectionString=ConnectionString
        New.Header=cPickle.dumps({"Content-type":"application/soap+xml", "charset":"utf-8"})
        New.Body="""<?xml version="1.0" encoding="utf-8"?>
                    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                    <soap12:Header>
                    <MultiSpeakMsgHeader Version="3.0" UserID="DCSI" Pwd="DCSI"
                    AppName="COOPIP"
                    AppVersion="1" Company="TCEC" CSUnits="feet"
                    CoordinateSystem=""
                    Datum=""
                    xmlns="http://www.multispeak.org/Version_3.0" />
                    </soap12:Header>
                    <soap12:Body>
                    <InitiateMeterReadByMeterNumber xmlns="http://www.multispeak.org/Version_3.0">
                    <meterNos>
                        <string>{{MeterNumber}}</string>
                    </meterNos>
                    <responseURL>http://192.168.100.19/coopip/cooptalk/</responseURL>
                    <transactionID>525</transactionID>
                    </InitiateMeterReadByMeterNumber>
                    </soap12:Body>
                    </soap12:Envelope>""".replace('{{MeterNumber}}', MeterNumber)
        New.URL=URL
        New.CreateDateTime=datetime.datetime.now()
        New.OutIndicator=True
        New.save()

    @staticmethod
    def OutGetMeterReadByMeterNumber(MeterNumber, ConnectionString='192.168.100.98:80', URL='/Optimum_Web_Service/MultiSpeak/30/MR_Server.asmx'):
        New=COOPTalk()
        New.ConnectionString=ConnectionString
        New.Header=cPickle.dumps({"Content-type":"application/soap+xml", "charset":"utf-8"})
        New.Body=u"""<?xml version="1.0" encoding="utf-8"?>
                    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                    <soap12:Header>
                    <MultiSpeakMsgHeader Version="3.0" UserID="DCSI" Pwd="DCSI"
                    AppName="COOPIP"
                    AppVersion="1" Company="TCEC" CSUnits="feet"
                    CoordinateSystem=""
                    Datum=""
                    xmlns="http://www.multispeak.org/Version_3.0" />
                    </soap12:Header>
                    <soap12:Body>
                    <GetReadingsByMeterNo xmlns="http://www.multispeak.org/Version_3.0">
                        <meterNo>{{MeterNumber}}</meterNo>
                        <startDate>2012-10-01T00:00:00.00</startDate>
                        <endDate>2080-12-16T00:00:00.00</endDate>
                   </GetReadingsByMeterNo>
                   </soap12:Body>
                   </soap12:Envelope>""".replace(u'{{MeterNumber}}', MeterNumber)
        New.URL=URL
        New.CreateDateTime=datetime.datetime.now()
        New.OutIndicator=True
        New.save()
        return New

    @staticmethod
    def OutInitiateMeterReadByMeterNumber(MeterNumber, ConnectionString='192.168.100.98:80', URL='/Optimum_Web_Service/MultiSpeak/30/MR_Server.asmx'):
        New=COOPTalk()
        New.ConnectionString=ConnectionString
        New.Header=cPickle.dumps({"Content-type":"application/soap+xml", "charset":"utf-8"})
        New.Body="""<?xml version="1.0" encoding="utf-8"?>
                    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                    <soap12:Header>
                    <MultiSpeakMsgHeader Version="3.0" UserID="DCSI" Pwd="DCSI"
                    AppName="COOPIP"
                    AppVersion="1" Company="TCEC" CSUnits="feet"
                    CoordinateSystem=""
                    Datum=""
                    xmlns="http://www.multispeak.org/Version_3.0" />
                    </soap12:Header>
                    <soap12:Body>
                    <InitiateMeterReadByMeterNumber xmlns="http://www.multispeak.org/Version_3.0">
                        <meterNos>
                            <string>{{MeterNumber}}</string>
                        </meterNos>
                    <responseURL>http://192.168.100.54/coopip/cooptalk/</responseURL>
                    <transactionID></transactionID>
                    </InitiateMeterReadByMeterNumber>
                    </soap12:Body>
                    </soap12:Envelope>""".replace('{{MeterNumber}}', MeterNumber)
        New.URL=URL
        New.CreateDateTime=datetime.datetime.now()
        New.OutIndicator=True
        New.save()

    @staticmethod
    def OutInitiateMeterReadByMeterNumberAndType(MeterNumber, ConnectionString='192.168.100.98:80', URL='/Optimum_Web_Service/MultiSpeak/30/MR_Server.asmx', Type='voltage'):
        New=COOPTalk()
        New.ConnectionString=ConnectionString
        New.Header=cPickle.dumps({"Content-type":"application/soap+xml", "charset":"utf-8"})
        New.Body="""<?xml version="1.0" encoding="utf-8"?>
                    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                    <soap12:Header>
                    <MultiSpeakMsgHeader Version="3.0" UserID="DCSI" Pwd="DCSI"
                    AppName="COOPIP"
                    AppVersion="1" Company="TCEC" CSUnits="feet"
                    CoordinateSystem=""
                    Datum=""
                    xmlns="http://www.multispeak.org/Version_3.0" />
                    </soap12:Header>
                    <soap12:Body>
                    <InitiateMeterReadByMeterNoAndType xmlns="http://www.multispeak.org/Version_3.0">
                        <meterNo>""" + MeterNumber + """</meterNo>
                        <responseURL>http://192.168.100.54/coopip/cooptalk/</responseURL>
                        <readingType>""" + Type + """</readingType>
                        <transactionID>{{transactionid}}</transactionID>
                    </InitiateMeterReadByMeterNoAndType>
                    </soap12:Body>
                    </soap12:Envelope>"""
        New.URL=URL
        New.CreateDateTime=datetime.datetime.now()
        New.OutIndicator=True
        New.save()
        New.Body=New.Body.replace('{{transactionid}}', str(New.id))
        New.save()

    @staticmethod
    def OutGetLatestReadings(LastReceived='', ConnectionString='192.168.100.98:80', URL='/Optimum_Web_Service/MultiSpeak/30/MR_Server.asmx'):
        New=COOPTalk()
        New.ConnectionString=ConnectionString
        New.Header=cPickle.dumps({"Content-type":"application/soap+xml", "charset":"utf-8"})
        New.Body="""<?xml version="1.0" encoding="utf-8"?>
                    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                    <soap12:Header>
                    <MultiSpeakMsgHeader Version="3.0" UserID="DCSI" Pwd="DCSI"
                        AppName="COOPIP"
                        AppVersion="1" Company="TCEC" CSUnits="feet"
                        CoordinateSystem=""
                        Datum="" LastSent=""
                        xmlns="http://www.multispeak.org/Version_3.0" />
                    </soap12:Header>
                    <soap12:Body>
                    <GetLatestReadings xmlns="http://www.multispeak.org/Version_3.0">
                    <lastReceived>{{LastReceived}}</lastReceived>
                    </GetLatestReading>
                    </soap12:Body>
                    </soap12:Envelope>""".replace('{{LastReceived}}', LastReceived)
        body = body
        New.URL=URL
        New.CreateDateTime=datetime.datetime.now()
        New.OutIndicator=True
        New.save()
    @staticmethod 
    def OutGetSupportedReadingTypes(LastReceived='', ConnectionString='192.168.100.98:80', URL='/Optimum_Web_Service/MultiSpeak/30/MR_Server.asmx'):
        New=COOPTalk()
        New.Header = ''
        New.ConnectionString = ''
        New.ConnectionString=ConnectionString
        New.Header=cPickle.dumps({"Content-type":"application/soap+xml", "charset":"utf-8"})
        New.Body="""<?xml version="1.0" encoding="utf-8"?>
                    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                    <soap12:Header>
                        <MultiSpeakMsgHeader Version="string" UserID="string" Pwd="string" AppName="string" AppVersion="string" Company="string" CSUnits="feet" CoordinateSystem="string" Datum="string" SessionID="string" PreviousSessionID="string" ObjectsRemaining="integer" LastSent="string" RegistrationID="string" xmlns="http://www.multispeak.org/Version_3.0" />
                    </soap12:Header>
                    <soap12:Body>
                    <GetSupportedReadingTypes xmlns="http://www.multispeak.org/Version_3.0" />
                    </soap12:Body>
                    </soap12:Envelope>"""
        New.URL=URL
        New.CreateDateTime=datetime.datetime.now()
        New.OutIndicator=True
        New.save()
    @staticmethod
    def InResponsePingURL(IncomingString):
        New=COOPTalk()
        New.Header = ''
        New.ConnectionString = ''
        New.Body=IncomingString
        New.Response="""<?xml version="1.0" encoding="utf-8"?>
                    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                    <soap12:Header>
                    <MultiSpeakMsgHeader Version="3.0" UserID="NotImplemented" Pwd="NotImplemented" AppName="COOPIP" AppVersion="Dev" Company="COOP"
                    CSUnits="feet" CoordinateSystem="" Datum="" SessionID=""
                    PreviousSessionID="" ObjectsRemaining="" LastSent="" xmlns="http://www.multispeak.org/Version_3.0" />
                    </soap12:Header>
                    <soap12:Body>
                    <PingURLResponse xmlns="http://www.multispeak.org/Version_3.0">
                    <PingURLResult />
                    </PingURLResponse>
                    </soap12:Body>
                    </soap12:Envelope>"""
        New.InDateTime=datetime.datetime.now()
        New.CreateDateTime=New.InDateTime
        New.InIndicator=True
        New.save()
        return New.Response

    @staticmethod
    def InResponseGetMethods(IncomingString): #FIXME, need to get info from request to effectively log
        New=COOPTalk()
        New.Header = ''
        New.ConnectionString = ''
        New.Body=IncomingString
        New.Response="""<?xml version="1.0" encoding="utf-8"?>
                    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                    <soap12:Header>
                    <MultiSpeakMsgHeader Version="3.0" UserID="NotImplemented" Pwd="NotImplemented" AppName="COOPIP" AppVersion="Dev" Company="COOP"
                    CSUnits="feet" CoordinateSystem="" Datum="" SessionID=""
                    PreviousSessionID="" ObjectsRemaining="" LastSent="" xmlns="http://www.multispeak.org/Version_3.0" />
                    </soap12:Header>
                    <soap12:Body>
                    <GetMethodsResponse xmlns="http://www.multispeak.org/Version_3.0">
                    <GetMethodsResult>
                        <string>Ping_URL</string>
                        <string>GetMethods</string>
                        <string>ReadingChangedNotification</string>
                        <string>FormattedBlockNotification</string>
                    </GetMethodsResult>
                    </GetMethodsResponse>
                    </soap12:Body>
                    </soap12:Envelope>"""
        New.InDateTime=datetime.datetime.now()
        New.CreateDateTime=New.InDateTime
        New.InIndicator=True

        New.save()
        return New.Response

    @staticmethod
    def InResponseReadingChangedNotification(IncomingString):
        New=COOPTalk()
        New.Header = ''
        New.ConnectionString = ''
        New.Body=IncomingString
        New.Response="""<?xml version="1.0" encoding="utf-8"?>
                    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                    <soap12:Header>
                    <MultiSpeakMsgHeader Version="3.0" UserID="NotImplemented" Pwd="NotImplemented" AppName="COOPIP" AppVersion="Dev" Company="COOP"
                    CSUnits="feet" CoordinateSystem="" Datum="" SessionID=""
                    PreviousSessionID="" ObjectsRemaining="" LastSent="" xmlns="http://www.multispeak.org/Version_3.0" />
                    </soap12:Header>
                    <soap12:Body>
                    <ReadingChangedNotificationResponse xmlns="http://www.multispeak.org/Version_3.0">
                    <ReadingChangedNotificationResult>
                    </ReadingChangedNotificationResult>
                    </ReadingChangedNotificationResponse>
                    </soap12:Body>
                    </soap12:Envelope>"""
        New.InDateTime=datetime.datetime.now()
        New.CreateDateTime=New.InDateTime
        New.InIndicator=True
        New.InResponseReadingChangedNotificationIndicator = True
        New.save()
        return New.Response

    
    @staticmethod
    def StringToDateTime(String):  #  Example AMR Date Time (COOPTALK) '2011-03-31T10:25:00-04:00'
        Year = String[:4]
        Month = String[5:7]
        DayOfMonth = String[8:10]
        Hour = String[11:13]
        Minute = String[14:16]
        Second = String[17:19]
        return datetime.datetime(int(Year), int(Month), int(DayOfMonth), int(Hour), int(Minute), int(Second))
    @staticmethod
    def CleanUpLogs():
        StartDate=datetime.datetime.now() - datetime.timedelta(days=7)
        EntriesToDelete = COOPTalk.objects.filter(CreateDateTime__lte=StartDate)
        for i in EntriesToDelete:
            i.delete()
    @staticmethod
    def GetMeterReadings(MeterDCSINumber):
        coopTalk = COOPTalk.OutGetMeterReadByMeterNumber(MeterDCSINumber)
        COOPTalk.SendAllOut()
        coopTalk=COOPTalk.objects.filter(id=coopTalk.id).get()
        soup = bs4.BeautifulStoneSoup(coopTalk.Response)
        MeterReadDict={}  #Format Key = Date, Value = [Positive Usage, Negative Usage, Phase]

        try:
            Current = soup.meterRead
        except AttributeError: 
            return MeterReadDict
        while(True):
            try:
                MeterNumber = Current.meterNo.contents[0]
            except AttributeError:
                return MeterReadDict
            if(not MeterNumber == MeterDCSINumber):
                raise('Meter DCSI Number:  ' + str(MeterDCSINumber) + ' does not match:  ' + str(MeterNumber))
            DateKey=Current.readingDate.contents[0].split('T')[0]
            PositiveUsage=Current.posKWh.contents[0]
            try:
                NegativeUsage=Current.negKWh.contents[0]
            except AttributeError:
                NegativeUsage=0
            Phase=Current.phase.contents[0]  
            MeterReadDict[str(DateKey)] = [str(PositiveUsage), str(NegativeUsage), str(Phase)]
            Current = Current.next_sibling
            if(not Current):
                return MeterReadDict

     
        

































